package com.shop.coupon.service.impl;

import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shop.common.core.domain.Result;
import com.shop.common.core.utils.StringUtils;
import com.shop.coupon.domain.Coupon;
import com.shop.coupon.domain.vo.CouponRequest;
import com.shop.coupon.mapper.CouponMapper;
import com.shop.coupon.service.CouponService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

@Service
public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> implements CouponService {

    @Autowired
    private RedisTemplate<String ,String > redisTemplate;

    @Autowired
    private CouponMapper couponMapper;

    // 使用可重入锁来保护更新操作的并发访问
    private final Lock publishLock = new ReentrantLock();
    private final Lock stopLock = new ReentrantLock();
//
//    @Override
//    public List<Coupon> selectCouponList(Coupon coupon) {
//        LambdaQueryWrapper<Coupon> queryWrapper = new LambdaQueryWrapper<>();
//        return baseMapper.selectList(queryWrapper);
//    }

    /**
     * 查询优惠券列表
     *
     * @param pageNum  当前页码
     * @param pageSize 每页记录数
     * @return 包含分页优惠券列表的成功结果
     */
    @Override
    public Result couponShow(Integer pageNum, Integer pageSize) {
        QueryWrapper<Coupon> queryWrapper = new QueryWrapper<>();
        Page<Coupon> couponPage = new Page<>(pageNum, pageSize);
        Page<Coupon> selectPage = baseMapper.selectPage(couponPage, queryWrapper);
        return Result.success(selectPage);
    }

    /**
     * 新增优惠券
     *
     * @param coupon 待新增的优惠券对象
     * @return 成功或失败的结果
     */
    @Transactional(rollbackFor = {Exception.class}, isolation = Isolation.SERIALIZABLE)
    @Override
    public Result couponInsert(Coupon coupon) {
        // 检查优惠券名称是否重复
        if (StringUtils.hasText(coupon.getCouponName()) &&
                baseMapper.selectCount(new LambdaQueryWrapper<Coupon>().eq(Coupon::getCouponName, coupon.getCouponName())) > 0) {
            throw new RuntimeException("优惠券名称重复");
        }
        // 检查优惠码是否存在冲突
        if (StringUtils.hasText(coupon.getCode()) &&
                baseMapper.selectCount(new LambdaQueryWrapper<Coupon>().eq(Coupon::getCode, coupon.getCode())) > 0) {
            throw new RuntimeException("优惠码存在冲突");
        }
        int insert = baseMapper.insert(coupon);
        return Result.success(insert);
    }

    /**
     * 修改优惠券信息
     *
     * @param coupon 待修改的优惠券对象
     * @return 成功或失败的结果
     */
    @Override
    public Result couponUpdate(Coupon coupon) {
        int updateCount = baseMapper.updateById(coupon);
        // 更新后清除缓存中的优惠券列表
        redisTemplate.delete("CouponServiceImpl-couponShow");
        return Result.success(updateCount);
    }

    /**
     * 删除优惠券
     *
     * @param id 待删除的优惠券ID
     * @return 成功或失败的结果
     */
    @Override
    public Result couponDelete(Long id) {
        Coupon coupon = baseMapper.selectById(id);
        if (coupon.getPublish() == 1) {
            return Result.success("优惠券正在发布中，请停止发布后再删除");
        }
        int deleteCount = baseMapper.deleteById(id);
        return Result.success(deleteCount);
    }

    /**
     * 根据ID查询优惠券详情
     *
     * @param id 优惠券ID
     * @return 查询到的优惠券详情
     */
    @Override
    public Result<Coupon> getCoupon(Long id) {
        Coupon coupon = baseMapper.selectById(id);
        return Result.success(coupon);
    }

    /**
     * 发布优惠券
     *
     * @param id 待发布的优惠券ID
     * @return 成功发布的数量
     */
    @Override
    @Transactional
    public Result couponUpdPublish(Long id) {
        publishLock.lock(); // 加锁
        try {
            Integer updatedCount = couponMapper.couponUpdPublish(id);
            return Result.success(updatedCount);
        } finally {
            publishLock.unlock(); // 解锁
        }
    }

    /**
     * 停止发布优惠券
     *
     * @param id 待停止发布的优惠券ID
     * @return 成功停止发布的数量
     */
    @Override
    @Transactional
    public Result couponUpdStop(Long id) {
        stopLock.lock(); // 加锁
        try {
            Integer updatedCount = couponMapper.couponUpdStop(id);
            return Result.success(updatedCount);
        } finally {
            stopLock.unlock(); // 解锁
        }
    }

    /**
     * 查询所有可选的优惠券
     *
     * @return 包含所有可选优惠券的成功结果
     */
    @Override
    public Result getSelectCoupon() {
        List<Coupon> selectCoupon = couponMapper.getSelectCoupon();
        return Result.success(selectCoupon);
    }

}
